/**
 * Copyright (C) 2018-2022
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.modules.coupon.rest;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import co.yixiang.api.ApiResult;
import co.yixiang.api.YshopException;
import co.yixiang.dozer.service.IGenerator;
import co.yixiang.enums.CouponEnum;
import co.yixiang.modules.activity.domain.YxStoreCouponUser;
import co.yixiang.modules.activity.domain.YxStoreCouponUserQrTemp;
import co.yixiang.modules.activity.service.mapper.YxStoreCouponUserQrTempMapper;
import co.yixiang.modules.logging.aop.log.AppLog;
import co.yixiang.common.aop.NoRepeatSubmit;
import co.yixiang.common.bean.LocalUser;
import co.yixiang.common.interceptor.AuthCheck;
import co.yixiang.modules.activity.service.YxStoreCouponIssueService;
import co.yixiang.modules.activity.service.YxStoreCouponUserService;
import co.yixiang.modules.activity.vo.StoreCouponUserVo;
import co.yixiang.modules.activity.vo.YxStoreCouponIssueQueryVo;
import co.yixiang.modules.activity.vo.YxStoreCouponUserQueryVo;
import co.yixiang.modules.coupon.param.YxStoreCouponQueryParam;
import co.yixiang.modules.user.domain.YxUser;
import co.yixiang.modules.user.service.YxUserService;
import co.yixiang.modules.user.vo.YxUserQueryVo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 优惠券 todo
 * </p>
 *
 * @author hupeng
 * @since 2019-10-02
 */
@Slf4j
@RestController
@Api(value = "优惠券", tags = "营销:优惠券")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CouponController {

    private final YxStoreCouponIssueService couponIssueService;
    private final YxStoreCouponUserService storeCouponUserService;

    /**
     * 可领取优惠券列表
     */
    @AuthCheck
    @GetMapping("/coupons")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码,默认为1", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "limit", value = "页大小,默认为10", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "productId", value = "产品ID", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "type", value = "优惠券类型 0通用券 1商品券 2内部券", paramType = "query", dataType = "int")
    })
    @ApiOperation(value = "可领取优惠券列表",notes = "可领取优惠券列表")
    public ApiResult<List<YxStoreCouponIssueQueryVo>> getList(@RequestParam(value = "page",defaultValue = "1") int page,
                                                               @RequestParam(value = "limit",defaultValue = "10") int limit,
                                                               @RequestParam(value = "productId",required = false) Long productId,
                                                               @RequestParam(value = "type",required = false) Integer type){
        Long uid = LocalUser.getUser().getUid();
        return ApiResult.ok(couponIssueService.getCouponList(page, limit,uid,productId,type));
    }

    /**
     * 领取优惠券
     */
    @AppLog(value = "领取优惠券", type = 1)
    @NoRepeatSubmit
    @AuthCheck
    @PostMapping("/coupon/receive")
    @ApiOperation(value = "领取优惠券",notes = "领取优惠券")
    public ApiResult<Boolean> receive(@Validated @RequestBody YxStoreCouponQueryParam param){
        Long uid = LocalUser.getUser().getUid();
        if(!NumberUtil.isNumber(param.getCouponId())){
           throw new YshopException("参数非法");
        }
        Integer couponId = Integer.valueOf(param.getCouponId());
        couponIssueService.issueUserCoupon(couponId,uid);
        return ApiResult.ok();
    }

    /**
     * 用户已领取优惠券
     */
    @AppLog(value = "查看已领取优惠券", type = 1)
    @AuthCheck
    @GetMapping("/coupons/user/{type}")
    @ApiOperation(value = "用户已领取优惠券",notes = "用户已领取优惠券")
    public ApiResult<List<YxStoreCouponUserQueryVo>> getUserList(){
        Long uid = LocalUser.getUser().getUid();
        List<YxStoreCouponUserQueryVo> list = storeCouponUserService.getUserCoupon(uid);
        return ApiResult.ok(list);
    }

    /**
     * 用户已领取优惠券pc
     */
    @AppLog(value = "用户已领取优惠券pc", type = 1)
    @AuthCheck
    @GetMapping("/coupons/user/pc/{type}")
    @ApiOperation(value = "用户已领取优惠券pc",notes = "用户已领取优惠券pc")
    public ApiResult<Object> getUserPCList(
            @RequestParam(value = "page", defaultValue = "1") int page,
            @RequestParam(value = "limit", defaultValue = "10") int limit, @PathVariable(value = "type") Integer type){
        Long uid = LocalUser.getUser().getUid();
        Map<String, Object> map = storeCouponUserService.getUserPCCoupon(uid,page,limit,type);
        Long total = (Long) map.get("total");
        Long totalPage = (Long) map.get("totalPage");
        return ApiResult.resultPage(total.intValue(), totalPage.intValue(), map.get("list"));
    }

    /**
     * 优惠券 订单获取
     */
    @AuthCheck
    @GetMapping("/coupons/order/{cartIds}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cartIds", value = "购物车ID,多个用,分割", paramType = "query", dataType = "int")
    })
    @ApiOperation(value = "优惠券订单获取",notes = "优惠券订单获取")
    public ApiResult<List<StoreCouponUserVo>> orderCoupon(@PathVariable String cartIds){
        Long uid = LocalUser.getUser().getUid();
        return ApiResult.ok(storeCouponUserService.beUsableCouponList(uid,cartIds));
    }

    @AuthCheck
    @GetMapping("/coupons/userOneOff/{id}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "表id", paramType = "query", dataType = "int")
    })
    @ApiOperation(value = "核销停车劵",notes = "核销停车劵")
    public ApiResult<String> couponsUserOffOne(@PathVariable String id){
        YxStoreCouponUserQrTemp yxStoreCouponUserQrTemp = getTempQr(id);
//        if(System.currentTimeMillis()-yxStoreCouponUserQrTemp.getCreateTime().getTime()>120*1000){
//            return ApiResult.fail("二维码已过期");
//        }
        YxUser user = LocalUser.getUser();

        Long uid = LocalUser.getUser().getUid();
        Integer couponUserId = yxStoreCouponUserQrTemp.getCouponUserId();
        YxStoreCouponUser byId = storeCouponUserService.getById(couponUserId);

        boolean power=false;
        if ((CouponEnum.TYPE_2.getValue()).equals(byId.getCouponType())){
            if (user.getIsParkingCoupon()==1){
                power=true;
            }
        }else if ((CouponEnum.TYPE_3.getValue()).equals(byId.getCouponType())){
            if (user.getIsDirectionalCoupon()==1){
                power=true;
            }
        }

        if( !power){
            return ApiResult.fail("无权核销券的类型");
        }

        if(CouponEnum.STATUS_0.getValue().equals(byId.getStatus())&&CouponEnum.FALI_0.getValue().equals(byId.getIsFail())){
            storeCouponUserService.update(Wrappers.<YxStoreCouponUser>lambdaUpdate()
                    .set(YxStoreCouponUser::getStatus, CouponEnum.STATUS_1.getValue())
                    .set(YxStoreCouponUser::getUseTime,new Date())
                    .set(YxStoreCouponUser::getOperatorId,uid)
                    .eq(YxStoreCouponUser::getId,couponUserId));

            return ApiResult.ok("ok");
        }else{
            return ApiResult.fail("二维码已使用或失效");
        }
    }

    @AuthCheck
    @GetMapping("/coupons/userOne/{id}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "表id", paramType = "query", dataType = "int")
    })
    @ApiOperation(value = "核销人员获取停车劵",notes = "核销人员获取停车劵")
    public ApiResult<Object> couponsUserOne(@PathVariable String id){
        //YxStoreCouponUserQrTemp yxStoreCouponUserQrTemp = yxStoreCouponUserQrTempMapper.selectById(id);
        YxStoreCouponUserQrTemp yxStoreCouponUserQrTemp=getTempQr(id);
        YxStoreCouponUser byId = storeCouponUserService.getById(yxStoreCouponUserQrTemp.getCouponUserId());
        YxUser byId1 = yxUserService.getById(byId.getUid());
        YxUserQueryVo convert = generator.convert(byId1, YxUserQueryVo.class);
        return ApiResult.ok(new HashMap<String,Object>(){{
            put("user",convert);
            put("coupon",byId);
        }});
    }

    @Autowired
    private IGenerator generator;


    private final YxStoreCouponUserQrTempMapper yxStoreCouponUserQrTempMapper;
    private final YxUserService yxUserService;
    private final RedisTemplate  redisTemplate;

    @AuthCheck
    @GetMapping("/coupons/temp/{id}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "yx_store_coupon_user表id", paramType = "query", dataType = "int")
    })
    @ApiOperation(value = "生成停车劵二维码id",notes = "生成停车劵二维码id")
    public ApiResult temp(@PathVariable Integer id){
        Long uid = LocalUser.getUser().getUid();
        List<YxStoreCouponUser> list = storeCouponUserService.list(Wrappers.<YxStoreCouponUser>lambdaQuery()
                .eq(YxStoreCouponUser::getUid, uid)
                .eq(YxStoreCouponUser::getId, id)
                .eq(YxStoreCouponUser::getStatus, CouponEnum.STATUS_0.getValue())
                .eq(YxStoreCouponUser::getIsFail, CouponEnum.FALI_0.getValue())
        );


        if(list.size()==0){
            return ApiResult.fail("该优惠券失效或不存在");
        }
        HashMap<String, Object> res = new HashMap<>();
        res.put("reload",1);

        String nextIdStr = IdUtil.getSnowflake(0,0).nextIdStr()+uid;
        YxStoreCouponUserQrTemp temp = new YxStoreCouponUserQrTemp();
        temp.setId(nextIdStr);
        temp.setCreateTime(new Date());
        temp.setIsDel(0);
        temp.setUid(uid);
        temp.setCouponUserId(id);
        seTempQr(temp);

        YxStoreCouponUser yxStoreCouponUser = list.get(0);
        if(CouponEnum.TYPE_3.getValue().equals(yxStoreCouponUser.getCouponType())){
            res.put("reload",0);
            List<YxStoreCouponUserQrTemp> yxStoreCouponUserQrTemps = yxStoreCouponUserQrTempMapper.selectList(Wrappers.<YxStoreCouponUserQrTemp>lambdaQuery()
                    .eq(YxStoreCouponUserQrTemp::getCouponUserId, id)
                    .eq(YxStoreCouponUserQrTemp::getUid, uid));
            if(yxStoreCouponUserQrTemps.size()>0){
                res.put("id",yxStoreCouponUserQrTemps.get(0).getId());
                return ApiResult.ok(res);
            }else{
                yxStoreCouponUserQrTempMapper.insert(temp);
            }
        }


        res.put("id",nextIdStr);
        return ApiResult.ok(res);
    }

    @AppLog(value = "核销人已扫码列表", type = 1)
    @AuthCheck
    @GetMapping("/coupons/list/{type}")
    @ApiOperation(value = "用户已领取优惠券pc",notes = "用户已领取优惠券pc")
    public ApiResult<Object> getCouponsList(
            @RequestParam(value = "page", defaultValue = "1") int page,
            @RequestParam(value = "limit", defaultValue = "10") int limit, @PathVariable(value = "type") String type){
        Long uid = LocalUser.getUser().getUid();

        Integer type2=0;
        if("isParkingCoupon".equals(type)){
            type2=(CouponEnum.TYPE_2.getValue());
        }else if("isDirectionalCoupon".equals(type)){
            type2=(CouponEnum.TYPE_3.getValue());
        }


        Map<String, Object> map = storeCouponUserService.getcouponListByOperatorId(page,limit,type2,uid);
        Long total = (Long) map.get("total");
        Long totalPage = (Long) map.get("totalPage");
        return ApiResult.resultPage(total.intValue(), totalPage.intValue(), map.get("list"));
    }



    public YxStoreCouponUserQrTemp  getTempQr(String id){
        YxStoreCouponUserQrTemp yxStoreCouponUserQrTemp = (YxStoreCouponUserQrTemp) redisTemplate.opsForValue().get(getKey()+id);
        if(yxStoreCouponUserQrTemp==null){
            YxStoreCouponUserQrTemp yxStoreCouponUserQrTemp1 = yxStoreCouponUserQrTempMapper.selectById(id);
            if(yxStoreCouponUserQrTemp1!=null){
                return yxStoreCouponUserQrTemp1;
            }
            throw new YshopException("优惠券不存在或过期");
        }
        seTempQr(yxStoreCouponUserQrTemp);
        return yxStoreCouponUserQrTemp;
    }
    private void  seTempQr(YxStoreCouponUserQrTemp temp){
        redisTemplate.opsForValue().set(getKey()+temp.getId(),temp,60, TimeUnit.SECONDS);
    }
    private String getKey(){
        return "qr:";
    }

}

